<template>
  <div class="box" :class="{ none: !isShow }">
    <el-upload
      action=""
      :drag="drag"
      :accept="accept"
      :disabled="disabled"
      list-type="picture-card"
      v-model:file-list="_fileList"
      :ref="(el) => (fileUpload = el)"
      :http-request="fnUploadRequest"
      :before-upload="handleUpload"
      :on-preview="handlePreview"
      :on-remove="handleRemove"
    >
      <el-icon><Plus /></el-icon>

      <template #tip v-show="tip">
        <div class="default_text">
          {{ tip }}
        </div>
      </template>
    </el-upload>
    <el-dialog v-model="dialogVisible">
      <img
        w-full
        :src="dialogImageUrl"
        class="previewImg"
        alt="Preview Image"
      />
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
  import { ref } from 'vue'
  import { Plus } from '@element-plus/icons-vue'
  import {
    ElMessage,
    dayjs,
    type UploadFile,
    type UploadFiles,
    type UploadProps,
    type UploadUserFile,
    ElMessageBox,
  } from 'element-plus'
  import { EstimatedTime, StrSplit } from '~/src/utils/utils'
  import { getosssts } from '~/src/api/dms/beCurrent'

  const props = defineProps({
    // 文件类型
    accept: {
      type: String,
      default: '.jpg,.png,.jpeg',
    },
    // 限制数量
    limit: {
      type: Number,
      default: 3,
    },
    // 是否禁用
    disabled: {
      type: Boolean,
      default: false,
    },
    // 提示
    tip: {
      type: String,
      default: '',
    },
    fileList: {
      type: Array,
      default: () => {
        return []
      },
    } as any,
    // 是否拖拽
    drag: {
      type: Boolean,
      default: false,
    },
    // 限制文件大小【MB】
    size: {
      type: Number,
      defailt: '',
    },
  })
  // 全局提示
  const proxy: any = getCurrentInstance()?.proxy
  const fileUpload = ref()
  const dialogImageUrl = ref('')
  const dialogVisible = ref(false)
  const fileName = ref('')
  const todayKey = dayjs().format('YYYY-MM-DD') //当前时间2023-08-07
  const folderName = 'dms'

  const emit = defineEmits(['delete'])

  // 数据
  let _fileList = ref<any>([...props.fileList])
  // 是否显示上传按钮
  let isShow = ref(true)

  watch(_fileList.value, (value) => {
    if (value.length < props.limit) {
      isShow.value = true
      return
    }
    isShow.value = false
  })

  // 请求
  const fnUploadRequest = async (options: any) => {
    const { onSuccess, onProgress, onError, file } = options
    fileName.value = file.name
    try {
      const configRes = await getosssts()
      const client = new OSS({
        region: configRes.data.regionId,
        accessKeyId: configRes.data.AccessKeyId,
        accessKeySecret: configRes.data.AccessKeySecret,
        // 从STS服务获取的安全令牌（SecurityToken）。
        stsToken: configRes.data.SecurityToken,
        // 填写Bucket名称，例如examplebucket。
        bucket: configRes.data.roleSessionName, // bucket名字
        secure: true,
      })

      const chunkSize = 1024 * 1024 * 1 // 分片大小
      const chunks = Math.ceil(file.size / chunkSize) // 分片数量
      ElMessage(`预计本次上传需要${EstimatedTime(chunks)}`)
      const updateName = `${folderName}/${todayKey}/${file.name}`
      const porps: any = {
        // 获取分片上传进度、断点和返回值。
        progress: (p: any, cpt: any, res: any) => {
          onProgress({ percent: p * 100 })
          // setProgress(p * 100)
        },
        headers: {},
        parallel: chunks,
        partSize: chunkSize,
        meta: { year: dayjs().format('YYYY'), people: `${folderName}` },
        mime: 'text/plain',
      }
      client
        .multipartUpload(`${updateName}`, file, { ...porps })
        .then((res: any) => {
          onSuccess(res.res.requestUrls[0])
        })
        .catch(function (err: any) {
          console.log(err)
          ElMessage({
            message: '上传失败',
            type: 'error',
          })
        })
    } catch (error) {}
  }
  // 上传前
  const handleUpload = (file: any) => {
    const { size } = file

    // 是否超出限制大小
    let isExceedSize = false

    if (props.size) {
      isExceedSize = size / 1024 / 1024 > props.size

      if (isExceedSize) {
        proxy.$Message(`上传文件大小不能超过 ${props.size}MB!`, 'warning')
        return false
      }
    }
  }
  // 预览
  const handlePreview: UploadProps['onPreview'] = (uploadFile) => {
    dialogImageUrl.value = uploadFile.url!
    dialogVisible.value = true
  }
  // 删除
  const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
    _fileList.value = uploadFiles
    emit('delete', uploadFile)
  }
  // 组件实例
  defineExpose({
    list: _fileList,
  })
</script>

<style lang="scss" scoped>
  .default_text {
    padding-top: 12px;
  }

  .none {
    :deep() {
      .el-upload--picture-card {
        display: none;
      }
    }
  }

  .box {
    :deep() {
      .el-upload-dragger {
        height: 100%;
        line-height: 80px;
      }
    }
  }
</style>
